feat: 场景驱动调度 — workflow 可配置引擎 + prompt 外部化 + 架构图重绘#12
Merged
Conversation
- 三层 JSON Schema (draft-07): tool/stage/condition/loop/pipeline_step/workflow - 工具别名支持 (name + display_name + aliases), 解决硬编码角色锁定场景问题 - 基于 santhosh-tekuri/jsonschema/v5 的 Schema 校验器, embed 打包 - YAML 配置加载器 + 跨字段语义校验 (工具引用完整性/别名唯一性/stage 可见性) - 用户配置统一 YAML, JSON 仅用于 schema 定义文件 - 87.6% 测试覆盖率, 含 8 valid + 12 invalid 用例 Refs #11
将 9 个 schema 定义文件从 JSON 转为 YAML 格式,与用户配置格式统一。 改动: - schemas/v1/*.json → schemas/v1/*.yaml(内容等价,YAML 语法) - $id 和 $ref 的 URL 保持 .json 后缀作为 URI 标识符(JSON Schema 标准约定) - loadEmbeddedSchemas: 读 YAML → 转 JSON → 注册到 compiler - go:embed 改为 *.yaml - 更新 types.go 注释和 README.md 文件名引用 测试覆盖: 87.0% (全项目测试通过) Refs #11
新建 internal/runtime 包,实现基于 schema.Workflow 的可配置调度引擎。 核心组件: - Tool 接口: 统一 agent/command/function 三种工具类型 - AgentTool: 包装 agent.Runner,调用 AI 智能体 - CommandTool: 通过 exec.CommandContext 执行 shell 命令 - ToolRegistry: 支持 name + alias 查找 - ExecutionContext: stage 间数据传递 + loop 状态维护 - Expression: 结构化 ExitCondition 求值(6 operator)+ 字符串表达式 - StageExecutor: 串行执行(when/on_blocked/input_from) - ParallelExecutor: 并行执行(all/any/first_success 三种 join) - LoopExecutor: 循环执行(exit_when/judge/max_iterations/max_consecutive_unknown) - Engine: 顶层入口,消费 *schema.Workflow Prompt 模板外部化: - prompts/*.md: 5 个模板文件(coding/review/issue-handling/issue-post/loop-judge) - PromptBuilder: 从 embed FS 加载 text/template 渲染 测试覆盖: 76.9% (76 个测试用例) 全项目测试通过 Refs #11
Stage 8 of scenario-driven scheduling refactor.
- dispatch.go: 624 -> 152 lines; Service now holds *runtime.Engine and
*schema.Workflow, Dispatch delegates to engine.Run
- delete prompts.go; 5 prompt templates migrated to
internal/runtime/prompts/*.md (rendered by prompt_builder.go)
- add runtime_adapter.go: ArtifactResolverAdapter bridges
pipeline.ArtifactSet <-> runtime.ArtifactResolver, routing LoadResult
by stage name to typed loaders
- add runtime/default_workflow.{go,yaml}: go:embed built-in default
workflow; --workflow flag supports external override
- cmd/worker/main.go: serviceFactory signature returns error to surface
workflow load failures; --workflow flag wired through buildService
- tests: add TestToPipelineResult + 2 end-to-end integration tests
(BlockedPath, CompletedPath); drop 9 dispatch state-machine tests
whose behavior is now covered by internal/runtime engine tests
- .gitignore: anchor 'worker' pattern to repo root ('/worker') so
cmd/worker/ is no longer ignored; add .trae/
Known gap: issue-post-blocked stage removed -- Engine terminates on
Blocked, so the stage could never run. issue-handling BLOCKED now
returns Blocked directly without posting a blocking comment. Future
Engine enhancement (on_blocked: continue) can restore this.
Verification: go build/vet/test all pass; runtime 76.1%, pipeline 70.3%
coverage.
Refs: #11
Complete Issue #11 verification standard: agent role definitions are now loaded from workflow config, no longer hardcoded in BuiltinAgents(). - delete Config fields: DefaultAgent, ReviewerAgent, IssuePostAgent, LoopJudgeAgent, MaxCodingReviewRounds, LoopJudgeStartRound (last 3 were dead code; first 3 now derived from workflow) - delete BuiltinAgents(), AgentByName(), AgentNames(), AgentRole struct (dead code: only config_test.go self-tested them) - delete defaultMaxCodingReviewRounds / defaultLoopJudgeStartRound consts - add runtime.lookupDisplayNameByPromptTemplate: derives display name from workflow.Tools by prompt_template, with fallback chain display_name > aliases[0] > name > empty - modify agent_tool.buildPromptData: derive DefaultAgent/ReviewerAgent/ IssuePostAgent from EC.Workflow instead of Config - Config now holds only Repo/IssueNumber/GitHubToken (3 runtime params) - update tool_test.go: add testWorkflow helper, pass workflow to IssueHandling test so prompt derivation works - add TestLookupDisplayNameByPromptTemplate (5 sub-cases) - update config_test.go: drop BuiltinAgents tests, simplify defaults test Backward compatible: default workflow's display_names match the old hardcoded values (developer/QA lead/PM), so prompts render identically without --workflow flag. Verification: go build/vet/test pass; runtime 76.5%, config 100% coverage. Refs: #11
Complete Issue #11 documentation standard: explain how to customize scheduling strategy via workflow config. - update 'why code-bee' bullets: replace '极简内核' with '场景驱动调度' - update tech stack table: scheduler now describes workflow-driven orchestration - add architecture overview with ASCII pipeline diagram - update usage example: add --workflow flag, fix output message - update project structure: add internal/runtime/ and internal/schema/, refresh package descriptions - add '自定义 Workflow' section: config structure, 3编排原语, 3 tool types, role name derivation, links to schema/default-workflow/prompts - update roadmap: mark scenario-driven scheduling, composable pipeline, tool aliases as completed; add on_blocked recovery item Refs: #11
- PromptBuilder 加载外部目录 .md 模板,overlay 同名内置模板 - Engine 通过 Functional Options 接收 WithPromptsDir - Service 透传 EngineOption,CLI 新增 --prompts-dir flag - 新增 overlay 单元测试 + 自定义 workflow 端到端集成测试 Closes #11 (prompts externalization gap)
Two-stage flag parsing had a bug: parseWorkflowFlag and parsePromptsDirFlag each registered only a single flag in their own FlagSet. Go's flag package stops parsing at the first unregistered flag, so when --repo (registered only in runCLI's FlagSet) appeared before --workflow/--prompts-dir, the probe functions returned empty strings and the flags were silently ignored (falling back to builtin workflow / builtin prompts). Discovered via smoke test: --prompts-dir /nonexistent/prompts did not error out, and the binary proceeded to dispatch with builtin prompts. Fix: merge the two probe functions into parseExtraFlags, which registers all known flags (--repo/--issue/--version as placeholders) so parsing proceeds past them. Add table-driven regression test covering 6 arg orderings including the previously broken 'flags after --repo' case. The same bug affected --workflow since its introduction; this commit fixes both.
…tion level Replace the single ASCII tree diagram with three Mermaid diagrams that show how the architecture is actually implemented: 1. Layered component architecture (flowchart TB) — CLI/pipeline/runtime/ schema four layers with all key structs (Engine, ToolRegistry, StageExecutor, AgentTool, PromptBuilder, ExecutionContext, ArtifactResolverAdapter, etc.) and interface-implementation edges (ArtifactResolver <- Adapter, Runner <- agent.Runner). 2. Dispatch call chain (sequenceDiagram) — full call timeline from runCLI -> Service.Dispatch -> Engine.Run -> StageExecutor -> AgentTool -> runner.Run, including result-file reset/read/write timing and early-termination semantics. 3. Config loading & data flow (flowchart LR) — workflow dual-source (go:embed builtin + --workflow override) and prompt overlay (--prompts-dir covers same-name builtin), plus result-file flow between stages via ExecutionContext. Add an Engine termination semantics table documenting how Blocked/ManualRequired/Completed trigger early return, with a note on the known issue-post-blocked gap.
- internal/runtime/expression_test.go: goimports formatting - internal/runtime/loop_executor_test.go: goimports formatting - internal/schema/loader.go: goimports formatting - internal/runtime/tool_test.go: SA4006 assign of tool is never used Found by CI golangci-lint.
…orts - expression.go: extract evalRegexCondition helper (18→reduced) - stage_executor.go: extract handleOnBlocked helper (19→reduced) - agent_tool.go: extract fillCoding/Review/IssuePost/LoopJudgePromptData helpers (30→reduced) - parallel_executor.go: extract aggregateStatus helper, remove unused base param (28→reduced) - loop_executor.go: extract executeBody & handleJudge helpers (31→reduced) - validator.go: check AddResource error, remove unused workflowSchemaPath const - main.go: add nolint:errcheck for fs.Parse in probe FlagSet - loop_judge_test.go: add nolint:unused for readLoopHistoryForTest All found by CI golangci-lint (errcheck, gocyclo, unused, goimports).
Extract postRound helper for per-round maintenance (ConsecutiveUnknown, judge, LastFeedback). Drops Execute from 18 to <=15 gocyclo threshold. Found by CI golangci-lint gocyclo check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue #11 核心重构:将 code-bee 的调度策略从硬编码四阶段 harness 重构为 YAML workflow 配置驱动的可编排引擎。用户可通过
--workflow和--prompts-dir完全自定义角色体系和调度流程,无需修改代码。12 个 Commits 按功能域分组
🏗️ 配置基础设施(Schema + Workflow)
5481c8cfeat(schema): add workflow schema and config loader — 三层 JSON Schema 定义(draft-07)、YAML 加载器、语义校验(工具引用完整性/别名唯一性/stage 可见性)、87.6% 测试覆盖率1f77397refactor(schema): unify schema files to YAML format — 9 个 schema 定义文件统一为 YAML,与用户配置格式一致⚙️ Runtime 可编排引擎
abcc923feat(runtime): implement configurable workflow engine — 新建internal/runtime包,包含 7 个核心组件:Engine、ToolRegistry(3 种 Tool 类型)、AgentTool、CommandTool、StageExecutor、ParallelExecutor、LoopExecutor、ExecutionContext、Expression 条件求值、PromptBuilder(5 个内置模板迁入 embed)7d34eb9refactor(pipeline): replace hardcoded dispatch with runtime.Engine — dispatch.go 从 624 行减至 152 行,Service 委托 Engine.Run 驱动;新增 ArtifactResolverAdapter 桥接 pipeline ↔ runtime;内置 default_workflow.yaml🔧 Agent 角色外部化
ea0070erefactor(config): externalize agent roles to workflow tools — 删除 BuiltinAgents() 硬编码,角色名从 workflow.Tools 按 prompt_template 派生(display_name > aliases[0] > name 回退链)📝 文档 + 架构图
21e1299docs: update README for scenario-driven workflow architecture — 更新项目结构、架构说明、新增「自定义 Workflow」章节820e5c0docs(README): redraw architecture diagrams with Mermaid — 3 个实现级 Mermaid 图(分层组件架构/Dispatch 调用时序/配置加载与数据流)+ Engine 终止语义表🎨 Prompt 模板外部化 + CLI bug 修复
ebbf777feat(runtime): support --prompts-dir — PromptBuilder 支持 overlay 外部模板;Engine Functional Options;--prompts-dirCLI flag;端到端集成测试5c94219fix(cli): parse --workflow/--prompts-dir when --repo precedes them — 修复 flag 两阶段解析 bug(--repo在--workflow/--prompts-dir前时后者被静默忽略),smoke test 发现,回归测试覆盖🧹 CI 修复
04880fbchore: sync go.mod/go.sum via go mod tidy — 修复// indirect标记和gopkg.in/check.v1缺失4e1f815fix(lint): goimports + staticcheck — 修复 4 个 goimports 格式化和 SA4006 未使用变量55ebe6dfix(lint): reduce cyclomatic complexity — 5 个函数提取 helper 降低复杂度(gocyclo 18-31 → 全部 ≤15),修复 errcheck/unused变更统计
internal/runtime/(20 files)、internal/schema/(15 files)internal/pipeline/prompts.go、internal/config/builtin_agents.gointernal/pipeline/dispatch.go(624→152 lines)Testing
go build/vet/test ./...全绿--prompts-dir错误路径、--workflow错误路径、自定义 workflow+prompts 联合加载Known Gaps
issue-post-blocked阶段因 Engine 遇 Blocked 立即终止而无法运行(README 已记录)FunctionTool仍为桩实现on_blocked: continue增强、测试覆盖率提至 85%+Closes #11